<?php

namespace app\common\service;

use EasyWeChat\MiniProgram\Application;
use think\Exception;

class WxappService
{
    /**
     * @Notes： 获取小程序实例
     * @AUthor：mt
     * @Date：2024/5/7
     * @Time：15:07
     * @return Application
     */
    public static function getApp(): Application
    {
        $config = config('mini_app')['default'];
        return new Application($config);
    }

    /**
     * @Notes： 获取手机号
     * @AUthor：mt
     * @Date：2024/5/7
     * @Time：15:08
     * @param string $sessionKey 用户会话密钥
     * @param string $iv 加密算法的初始向量
     * @param string $encryptedData 包括敏感数据在内的完整用户信息的加密数据
     * @return string
     * @throws Exception
     */
    public static function getPhoneNumber(string $sessionKey, string $iv, string $encryptedData): string
    {
        try {
            $app = self::getApp();
            $result = $app->encryptor->decryptData($sessionKey, $iv, $encryptedData);
            // 4.x没有phone_number组件，通常前端解密后传给后端
            // 这里仅作示例，具体实现需结合小程序前端解密逻辑
            return $result['purePhoneNumber'] ?? '';
        } catch (\Throwable $e) {
            return '';
        }
    }

    /**
     * @Notes： 获取用户openid和unionid
     * @AUthor：mt
     * @Date：2024/5/7
     * @Time：16:04
     * @param string $code 登录凭证
     * @return array
     * @throws Exception
     */
    public static function jscode2session(string $code): array
    {
        try {
            $app = self::getApp();
            $result = $app->auth->session($code);
            if (isset($result['errcode']) && $result['errcode'] !== 0) {
                throw new Exception($result['errmsg']);
            }
            return [
                'open_id'     => $result['openid'] ?? '',
                'union_id'    => $result['unionid'] ?? '',
                'session_key' => $result['session_key'] ?? ''
            ];
        } catch (\Throwable $e) {
            \think\Log::write('获取用户信息失败：' . $e->getMessage());
            // throw new Exception('获取用户信息失败：' . $e->getMessage());
            return [
                'open_id'     => '',
                'union_id'    => '',
                'session_key' => ''
            ];
        }
    }

    /**
     * 发送订阅消息
     * @param string $openid 用户openid
     * @param string $templateId 模板ID
     * @param array $data 模板数据
     * @param string $page 跳转页面
     * @return bool
     * @throws Exception
     */
    public static function sendSubscribeMessage(string $openid, string $templateId, array $data, string $page = ''): bool
    {
        try {
            $app = self::getApp();
            $result = $app->template_message->send([
                'touser' => $openid,
                'template_id' => $templateId,
                'page' => $page,
                'data' => $data
            ]);
            if (isset($result['errcode']) && $result['errcode'] !== 0) {
                throw new Exception($result['errmsg']);
            }
            return true;
        } catch (\Throwable $e) {
            throw new Exception('发送订阅消息失败：' . $e->getMessage());
        }
    }

    /**
     * 生成小程序码
     * @param string $scene 场景值
     * @param string $page 页面路径
     * @param array $options 其他参数
     * @return string
     * @throws Exception
     */
    public static function getWxacode(string $scene, string $page = '', array $options = []): string
    {
        try {
            $app = self::getApp();
            $response = $app->app_code->getUnlimit($scene, [
                'page' => $page,
                'check_path' => $options['check_path'] ?? true,
                'env_version' => $options['env_version'] ?? 'release',
                'width' => $options['width'] ?? 430
            ]);
            if (isset($response['errcode']) && $response['errcode'] !== 0) {
                throw new Exception($response['errmsg']);
            }
            return $response['buffer'] ?? '';
        } catch (\Throwable $e) {
            throw new Exception('生成小程序码失败：' . $e->getMessage());
        }
    }

    /**
     * 获取小程序URL Link
     * 
     */
    public static function getUrlLink(string $scene = '', string $page = '', array $options = []): string
    {
        // 获取小程序URL  Link
        // $WxappService = new \app\common\service\WxappService();
        // $url = $WxappService->getUrlLink('', '');
        $app = self::getApp();
        // 获取 access_token
        $accessToken = $app->access_token->getToken()['access_token'];

        // 组装参数
        $params = [
            'path' => $page, // 小程序页面路径
            'query' => $scene, // 形如 'foo=bar'
            // 'env_version' => $options['env_version'] ?? 'release',
            // 其他参数可选
        ];

        // 请求微信接口
        $url = "https://api.weixin.qq.com/wxa/generate_urllink?access_token={$accessToken}";
        $response = $app->httpPostJson($url, $params);
        // print_r($response);exit;
        return $data['url_link'] ?? '';
    }
}